﻿using Microsoft.Practices.Unity;
using Sasa.QualityTools.CodeAnalysis.Core.Views;
using Sasa.QualityTools.CodeAnalysis.Core.VisualStudio;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Commands.Behaviors.CodeAnalysis
{
    public class PerformCodeAnalysisBehavior : ICommandBehavior<CodeAnalysisCommandExecutionContext>
    {
        private IUnityContainer container;


        public PerformCodeAnalysisBehavior(IUnityContainer container)
        {
            this.container = container;
        }


        public void Behave(CodeAnalysisCommandExecutionContext context)
        {
            if (context.Progress.CodeAnalyzers.Where(o => o.Status != CodeAnalysisStatus.Skip).Count() == 0)
            {
                context.Cancel("FxCop Integrator didn't perform code analysis because it couldn't find any targets that should be analyzed.");
                return;
            }

            var view = container.Resolve<ICodeAnalysisProgressView>();
            context.Progress.CodeAnalysisCompleted += delegate
            {
                view.RunOnUIThread(() => view.Close());
            };
            context.Progress.CodeAnalysisCanceled += delegate
            {
                view.RunOnUIThread(() => view.Close());
            };
            context.Progress.CodeAnalysisFailed += (sender, e) =>
            {
                OpenErrorReportView(e.FailedTargets);
            };
            context.Progress.CloseRequired += delegate
            {
                view.RunOnUIThread(() => view.Close());
            };

            context.Progress.PerformCodeAnalysis();

            view.DataContext = context.Progress;
            view.ShowModal();
        }

        private void OpenErrorReportView(IEnumerable<string> failedTargets)
        {
            var ide = container.Resolve<IIde>();

            var model = new ErrorReportViewModel();
            model.VisualStudioVersion = ide.VersionInfo;
            model.ErrorInfo = "Following targets can't be analyzed." + Environment.NewLine +
                String.Join(Environment.NewLine, failedTargets.Select(o => "* " + o));

            var view = container.Resolve<IErrorReportView>();
            view.DataContext = model;
            model.ShowWebPageRequired += (sender, e) =>
            {
                ide.Navigate(e.Url);
            };
            model.CloseRequired += delegate
            {
                view.Close();
            };

            view.Show();
        }
    }
}
